﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using G.Model;
using G.Model.Converters;

namespace G.Model
{
    [CollectionDataContract]
    public class GamePlayerDefs :  ICollection<GamePlayerDef>
    {
        public delegate void PlayersChangedHandler();
        public delegate void PlayerHandler(GamePlayerDef player);
        
        public event PlayersChangedHandler PlayersChangedEvent;
        public event PlayerHandler PlayerRemovedEvent;
        public event PlayerHandler PropertyChangedEvent;
        
        public static readonly Color COLOR_1 = Color.LightCyan;
        public static readonly Color COLOR_2 = Color.SkyBlue;
        public static readonly Color COLOR_3 = Color.LightYellow;

        private readonly Dictionary<string, GamePlayerDef> _Collection;
        
        public GamePlayerDefs() : this(null) { }
        
        public GamePlayerDefs(GameSpaceDef game)
        {
            _Collection = new Dictionary<string, GamePlayerDef>();
        }
        
        [Browsable(false)]
        public Dictionary<string, GamePlayerDef> Dictionary
        {
            get { return _Collection; }
        }
        
        public void RemoveNotFound(ICollection<string> list)
        {
            List<string> remove = new List<string>();
            foreach(string key in list) 
            {
                if (_Collection.ContainsKey(key))
                {
                    remove.Add(key);
                }            
            }
            RemoveKeys(remove);
        }

        public void RemoveKeys(ICollection<string> remove)
        {
            foreach (string key in remove)
            {
                _Collection.Remove(key);
                if (PlayersChangedEvent != null)
                {
                    PlayersChangedEvent();
                }
            }
        }

        public void DeterminePlayers(GameSpaceDef pGameDef)
        {
            foreach (string name in pGameDef.GameElementDefs.PlayerNames)
            {
                GamePlayerDef player = new GamePlayerDef(pGameDef, name);
                if (!_Collection.ContainsKey(player.Name))
                {
                    Add(player);
                }
            }

            List<GamePlayerDef> remove = new List<GamePlayerDef>();
            foreach (GamePlayerDef player in this)
            {
                if (!pGameDef.GameElementDefs.PlayerNames.Contains(player.Name))
                {
                    remove.Add(player);
                }
            }
            
            foreach (GamePlayerDef player in remove)
            {
                pGameDef.GamePlayerDefs.Remove(player);
            }
        }

        public void DetermineColors()
        {
            List<Color> colors = new List<Color>();
            
            foreach (GamePlayerDef player in this)
            {
                if (player.Name == "Player1")
                {
                    colors.Add(COLOR_1);
                }
                else if (player.Name == "Player2")
                {
                    colors.Add(COLOR_2);
                }
                else 
                {
                    colors.Add(COLOR_3);
                }
            }
            
            foreach (GamePlayerDef player in this)
            {
                if (colors.Contains(player.Color))
                {
                    colors.Remove(player.Color);
                }
                else
                {
                    Color c = colors[0];
                    colors.RemoveAt(0);
                    player.Color = c;
                }
            }
        }

        public void FirePropertyChanged(GamePlayerDef subject)
        {
            if (PropertyChangedEvent != null)
            {
                PropertyChangedEvent(subject);
            }
        }
        
        public int Count
        {
            get { return _Collection.Count; }
        }
        
        public bool IsReadOnly
        {
            get { return false; }
        }
        
        public void Add(GamePlayerDef item)
        {
            _Collection.Add(item.Name, item);
            DetermineColors();
            if (PlayersChangedEvent != null)
            {
                PlayersChangedEvent();
            }
        }
        
        public void Clear()
        {
            _Collection.Clear();
        }
        
        public bool Contains(GamePlayerDef item)
        {
            return _Collection.ContainsKey(item.Name);
        }
        
        public bool Contains(string key)
        {
            return _Collection.ContainsKey(key);
        }
        
        public void CopyTo(GamePlayerDef[] array, int arrayIndex)
        {
            _Collection.Values.CopyTo(array, arrayIndex);
        }
        
        public bool Remove(GamePlayerDef item) 
        {
            bool b = _Collection.Remove(item.Name);
            if (PlayersChangedEvent != null)
            {
                PlayersChangedEvent();
            }
            if (PlayerRemovedEvent != null)
            {
                PlayerRemovedEvent(item);
            }
            return b;
        }
        
        public IEnumerator<GamePlayerDef> GetEnumerator()
        {
            return _Collection.Values.GetEnumerator();
        }
        
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return _Collection.Values.GetEnumerator();
        }
        
        public GamePlayerDef this[string key]
        {
            get
            {
                return _Collection[key];
            }
            set
            {
                _Collection[key] = value;
            }
        }
        
    }
}
